-- Scheme Module manager -- by Alundaio -- Типы схем: stype_stalker = 0 stype_mobile = 1 stype_item = 2 stype_heli = 3 stype_restrictor = 4 stype_trader = 5 ---------------------------------------------------------------------- -- Загрузка схем: ---------------------------------------------------------------------- -- Generic Schemes LoadScheme("xr_meet", "meet", stype_stalker) LoadScheme("xr_wounded", "wounded", stype_stalker) LoadScheme("xr_danger", "danger", stype_stalker) LoadScheme("xr_abuse", "abuse", stype_stalker) LoadScheme("xr_gather_items", "gather_items", stype_stalker) LoadScheme("xr_help_wounded", "help_wounded", stype_stalker) LoadScheme("xr_corpse_detection", "corpse_detection", stype_stalker) --LoadScheme("axr_stalker_panic", "stalker_panic", stype_stalker) -- working but not ideal behavior so it's disabled LoadScheme("axr_npc_vs_heli", "npc_vs_heli", stype_stalker) LoadScheme("axr_npc_vs_box", "npc_vs_box", stype_stalker) LoadScheme("axr_fight_from_cover", "fight_from_cover", stype_stalker) LoadScheme("axr_radio_in_heli", "radio_in_heli", stype_stalker) LoadScheme("axr_turn_on_campfire", "turn_on_campfire", stype_stalker) LoadScheme("rx_ff", "rx_ff", stype_stalker) --LoadScheme("rx_gl", "gl", stype_stalker) --known to cause issues enable at your own risk --LoadScheme("xrs_facer", "facer", stype_stalker) LoadScheme("xrs_kill_wounded", "kill_wounded", stype_stalker) --LoadScheme("axr_anomaly_planner", "evade_anom", stype_stalker) ---------------------------------------------------------------------- -- Загрузка модулей сталкеров: ---------------------------------------------------------------------- LoadScheme("xr_walker", "walker", stype_stalker) LoadScheme("xr_remark", "remark", stype_stalker) LoadScheme("xr_cover", "cover", stype_stalker) LoadScheme("xr_sleeper", "sleeper", stype_stalker) LoadScheme("xr_camper", "camper", stype_stalker) LoadScheme("xr_combat", "combat", stype_stalker) LoadScheme("xr_death", "death", stype_stalker) LoadScheme("xr_hit", "hit", stype_stalker,stype_mobile,stype_heli) LoadScheme("xr_combat_ignore", "combat_ignore", stype_stalker,stype_mobile) LoadScheme("xr_combat_zombied", "combat_zombied", stype_stalker) LoadScheme("xr_patrol", "patrol", stype_stalker) LoadScheme("xr_smartcover", "smartcover", stype_stalker) LoadScheme("xr_companion", "companion", stype_stalker) LoadScheme("xr_animpoint", "animpoint", stype_stalker) LoadScheme("xr_reach_task", "reach_task", stype_stalker) ---------------------------------------------------------------------- -- Загрузка модулей монстров: ---------------------------------------------------------------------- LoadScheme("mob_remark", "mob_remark", stype_mobile) LoadScheme("mob_walker", "mob_walker", stype_mobile) LoadScheme("mob_combat", "mob_combat", stype_mobile) LoadScheme("mob_death", "mob_death", stype_mobile) LoadScheme("mob_jump", "mob_jump", stype_mobile) LoadScheme("mob_home", "mob_home", stype_mobile) ---------------------------------------------------------------------- -- Загрузка модулей Торговца ---------------------------------------------------------------------- LoadScheme("mob_trader", "mob_trader", stype_trader) LoadScheme("mob_trade", "mob_trade", stype_trader) ---------------------------------------------------------------------- -- Загрузка модулей физических объектов: ---------------------------------------------------------------------- LoadScheme("ph_car", "ph_car", stype_item) LoadScheme("ph_door", "ph_door", stype_item) LoadScheme("ph_idle", "ph_idle", stype_item) LoadScheme("ph_hit", "ph_hit", stype_item) LoadScheme("ph_on_hit", "ph_on_hit", stype_item) LoadScheme("ph_button", "ph_button", stype_item) LoadScheme("ph_code", "ph_code", stype_item) LoadScheme("ph_death", "ph_on_death", stype_item) LoadScheme("ph_minigun", "ph_minigun", stype_item) LoadScheme("ph_oscillate", "ph_oscillate", stype_item) LoadScheme("ph_sound", "ph_sound", stype_item) ---------------------------------------------------------------------- -- Загрузка модулей вертолёта: ---------------------------------------------------------------------- LoadScheme("heli_move", "heli_move", stype_heli) ---------------------------------------------------------------------- -- Загрузка модулей рестрикторов: ---------------------------------------------------------------------- LoadScheme("sr_no_weapon", "sr_no_weapon", stype_restrictor) LoadScheme("sr_teleport", "sr_teleport", stype_restrictor) LoadScheme("sr_idle", "sr_idle", stype_restrictor) LoadScheme("sr_light", "sr_light", stype_restrictor) LoadScheme("sr_timer", "sr_timer", stype_restrictor) LoadScheme("sr_psy_antenna", "sr_psy_antenna", stype_restrictor) LoadScheme("sr_postprocess", "sr_postprocess", stype_restrictor) LoadScheme("sr_particle", "sr_particle", stype_restrictor) LoadScheme("sr_cutscene", "sr_cutscene", stype_restrictor) LoadScheme("sr_monster", "sr_monster", stype_restrictor) LoadScheme("sr_crow_spawner", "sr_crow_spawner", stype_restrictor) LoadScheme("sr_silence", "sr_silence", stype_restrictor) LoadScheme("sr_deimos", "sr_deimos", stype_restrictor) ---------- LoadScheme("axr_beh", "beh", stype_stalker) LoadScheme("xr_campfire_point", "campfire_point", stype_stalker) function on_game_start() for scheme,filename in pairs(_G.schemes) do if (_G[filename] and _G[filename].on_game_start) then _G[filename].on_game_start() end end end ---------------------------------------- -- enable_generic_schemes -- -- currently only implemented for stype_stalker schemes -- automates binding for generic schemes ONLY -- xr_logic already handles 'active section' schemes by calling set_scheme -- active section schemes are schemes that only execute if they are activated by custom logic (ie. walker@my_section) ---------------------------------------- --[[ Alundaio Beware if you are adding your own generic schemes: This is a two-step process. We must ensure that ALL actions and evaluators are created and assigned to the motivation_action_manager before we add preconditions and effects to the actions. Otherwise it can lead to unknown script behavior and bugs that will not be apparent unless lua logging is enabled by the engine. This is because it's possible that evaluators for assigned property ids will not exist when being added to an action. This is not an issue for 'active section' schemes because they will never need to assign evaluator properties of eachother to their actions as preconditions. setup_generic_scheme is where the action and evaluator are created and assigned. Assign it's default (i.e. it's own id) effects/precondition if necessary. It is okay to assign engine properties to the action here, (i.e. stalker_ids) since they should exist at time of binding. look at any scheme I've written that has scheme_type = generic in the comment header as an example. configure_actions is where properties of other generic schemes may be safely added to actions. --]] local temp = {} function enable_generic_schemes(npc,ini,section,stype) if not (npc) then abort("CRITICAL ERROR: enable_generic_schemes NPC IS NIL!") return end local filename for scheme,v in pairs(_G.schemes_by_stype[stype]) do filename = _G.schemes[scheme] if (filename and _G[filename] and _G[filename].setup_generic_scheme) then --printf("DEBUG: setup_generic_scheme npc=%s scheme=%s",npc and npc:name(),scheme) temp[scheme] = empty_table(temp[scheme]) _G[filename].setup_generic_scheme(npc,ini,scheme,section,stype,temp[scheme]) end end local id = npc:id() for scheme,v in pairs(_G.schemes_by_stype[stype]) do if (temp[scheme] and temp[scheme].needs_configured) then filename = _G.schemes[scheme] if (filename and _G[filename] and _G[filename].configure_actions) then --utils_data.debug_write(strformat("DEBUG: configure_actions npc=%s scheme=%s",npc and npc:name(),scheme)) if not (db.storage[id][scheme]) then printe("!ERROR: storage for db.storage[%s][%s] not setup!",id,scheme) end _G[filename].configure_actions(npc,ini,scheme,section,stype,temp[scheme]) end end end if (stype == stype_stalker) then stalker_generic.reset_invulnerability(npc,ini,section) local info_section = ini:r_string_ex(section,"info") if (info_section) then stalker_generic.set_npc_info(npc,ini,"info",info_section) end elseif (stype == stype_mobile) then stalker_generic.reset_invulnerability(npc,ini,section) elseif (stype == stype_item) then local hit_section = ini:r_string_ex(section,"on_hit") if hit_section then ph_on_hit.set_scheme(npc, ini, "ph_on_hit", hit_section) end end end function reset_generic_schemes(npc,scheme,section) if not (npc) then abort("CRITICAL ERROR: reset_generic_schemes NPC IS NIL!") return end --utils_data.debug_write(strformat("DEBUG: reset_generic_scheme npc=%s scheme=%s section=%s",npc and npc:name(),scheme,section)) local st = db.storage[npc:id()] if not (st) then printe("!ERROR: reset_generic_schemes: storage is nil! npc=%s scheme=%s section=%s",npc and npc:name(),scheme,section) return end st.exit_from_smartcover_initialized = nil if not st.stype then return end local filename for scheme,v in pairs(_G.schemes_by_stype[st.stype]) do filename = _G.schemes[scheme] if (filename and _G[filename] and st[scheme] and _G[filename].reset_generic_scheme) then --printf("DEBUG: reset_generic_schemes npc=%s scheme=%s storage_exists=%s",npc and npc:name(),scheme,st[scheme]) _G[filename].reset_generic_scheme(npc,scheme,section,st.stype,st) end end if (st.stype == stype_stalker) then restrictor_manager.get_restrictor_manager(npc):reset_restrictions(st, section) xr_hear.reset_hear_callback(st, section) stalker_generic.reset_threshold(npc, scheme, st, section) stalker_generic.reset_show_spot(npc, scheme, st, section) stalker_generic.reset_invulnerability(npc, st.ini, section) stalker_generic.reset_group(npc, st.ini, section) stalker_generic.take_items_enabled(npc, scheme, st, section) stalker_generic.can_select_weapon(npc, scheme, st, section) elseif st.stype == modules.stype_mobile then xr_logic.mob_release(npc) if get_clsid(npc) == clsid.bloodsucker_s then if scheme == "nil" then npc:set_manual_invisibility(false) else npc:set_manual_invisibility(true) end end stalker_generic.reset_invulnerability(npc, st.ini, section) restrictor_manager.get_restrictor_manager(npc):reset_restrictions(st, section) xr_hear.reset_hear_callback(st,section) elseif st.stype == modules.stype_trader then stalker_generic.reset_show_spot(npc, scheme, st, section) elseif st.stype == modules.stype_item then npc:set_callback(callback.use_object, nil) npc:set_nonscript_usable(true) if (get_clsid(npc) == clsid.car) then npc:destroy_car() xr_logic.mob_release(npc) end end end function disable_generic_schemes(npc, stype) if not (npc) then abort("CRITICAL ERROR: disable_generic_schemes NPC IS NIL!") return end --utils_data.debug_write(strformat("DEBUG: disable_generic_schemes npc=%s stype=%s",npc and npc:name(),stype)) local st = db.storage[npc:id()] if not (st) then printe("!ERROR: disable_generic_schemes : storage is nil! npc=%s scheme=%s section=%s",npc and npc:name(),scheme,section) return end local filename for scheme,v in pairs(_G.schemes_by_stype[stype]) do filename = _G.schemes[scheme] if (filename and _G[filename] and st[scheme] and _G[filename].disable_generic_scheme) then --printf("DEBUG: disable_generic_scheme npc=%s scheme=%s",npc and npc:name(),scheme) _G[filename].disable_generic_scheme(npc,scheme,stype) end end if (stype == stype_stalker) then stalker_generic.disable_invulnerability(npc) elseif stype == modules.stype_mobile then stalker_generic.disable_invulnerability(npc) end end function add_common_precondition(scheme,action) if not action then return end --utils_data.debug_write(strformat("DEBUG: modules: add_common_precondition %s",scheme)) local wp = world_property action:add_precondition(wp(xr_evaluators_id.stohe_meet_base + 1, false)) action:add_precondition(wp(xr_evaluators_id.sidor_wounded_base, false)) action:add_precondition(wp(xr_evaluators_id.abuse_base, false)) action:add_precondition(wp(xr_evaluators_id.wounded_exist, false)) if (_G.schemes["corpse_detection"]) then action:add_precondition(wp(xr_evaluators_id.corpse_exist, false)) end for _scheme,filename in pairs(_G.schemes) do if (_G[filename] and _G[filename].npc_add_precondition) then _G[filename].npc_add_precondition(action) end end end